package com.intelligent.aspect;


import com.intelligent.annotation.OperationLog;
import com.intelligent.entity.OperationLogs;
import com.intelligent.mapper.OperationLogsMapper;
import com.intelligent.utils.OperationLogUtil;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@RequiredArgsConstructor
public class OperationLogAspect {

    private final OperationLogsMapper operationLogsMapper;

    @Pointcut("@annotation(operationLog)")
    public void logPointcut(OperationLog operationLog) {}

    @AfterReturning(pointcut = "logPointcut(operationLog)", returning = "result")
    public void afterReturning(JoinPoint joinPoint, OperationLog operationLog, Object result) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Object[] args = joinPoint.getArgs();
        String[] paramNames = signature.getParameterNames();

        // SpEL 解析
        String content = parseSpEL(operationLog.content(), paramNames, args, result);

        // 获取当前登录用户信息
        String employeeAccount = getCurrentUserAccount();
        Integer userId = getCurrentUserId();

        // 特殊处理登录接口：从SpEL解析结果中提取用户账号
        if ((employeeAccount == null || employeeAccount.trim().isEmpty()) && 
            "登录模块".equals(operationLog.module()) && content != null && content.contains("账号：")) {
            // 从content中提取用户账号，格式："用户登录系统，账号：username"
            int accountIndex = content.indexOf("账号：");
            if (accountIndex != -1) {
                String extractedAccount = content.substring(accountIndex + 3).trim();
                if (!extractedAccount.isEmpty()) {
                    employeeAccount = extractedAccount;
                }
            }
        }

        // 如果仍无法获取用户账号，使用默认值确保日志记录
        if (employeeAccount == null || employeeAccount.trim().isEmpty()) {
            employeeAccount = "unknown@system.com";
        }
        if (userId == null) {
            userId = 0;
        }

        OperationLogs log = OperationLogUtil.buildLog(
                employeeAccount,
                userId,
                operationLog.module(),
                content
        );

        operationLogsMapper.insert(log);
    }

    private String parseSpEL(String spel, String[] paramNames, Object[] args, Object result) {
        if (spel == null || spel.isEmpty()) {
            return "";
        }
        
        try {
            ExpressionParser parser = new SpelExpressionParser();
            EvaluationContext context = new StandardEvaluationContext();
            for (int i = 0; i < paramNames.length; i++) {
                context.setVariable(paramNames[i], args[i]);
            }
            context.setVariable("result", result); // 支持返回值
            return parser.parseExpression(spel).getValue(context, String.class);
        } catch (Exception e) {
            // 如果SpEL解析失败，返回原始字符串（去掉SpEL表达式标记）
            // 这样可以避免因为中文字符或其他特殊字符导致的解析错误
            return spel.replaceAll("#\\w+(\\.\\w+)*", "[参数]");
        }
    }

    /**
     * 获取当前登录用户账号
     */
    private String getCurrentUserAccount() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                // 优先从请求属性获取（AuthInterceptor设置的真实数据）
                Object accountAttr = request.getAttribute("CURRENT_USER_ACCOUNT");
                if (accountAttr != null) {
                    return accountAttr.toString();
                }
                // 备用：从请求头获取
                String userAccount = request.getHeader("X-User-Account");
                if (userAccount != null && !userAccount.isEmpty()) {
                    return userAccount;
                }
            }
        } catch (Exception e) {
            // 忽略异常
        }
        return null; // 不使用默认值
    }

    /**
     * 获取当前登录用户ID
     */
    private Integer getCurrentUserId() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                // 优先从请求属性获取（AuthInterceptor设置的真实数据）
                Object userIdAttr = request.getAttribute("CURRENT_USER_ID");
                if (userIdAttr != null) {
                    return Integer.parseInt(userIdAttr.toString());
                }
                // 备用：从请求头获取
                String userId = request.getHeader("X-User-Id");
                if (userId != null && !userId.isEmpty()) {
                    return Integer.parseInt(userId);
                }
            }
        } catch (Exception e) {
            // 忽略异常
        }
        return null; // 不使用默认值
    }
}
